package com.css.fxfzcpxx.modules.earthquakeDisaster.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzcpxx.base.attachment.entity.AttachmentInfoEntity;
import com.css.fxfzcpxx.base.attachment.service.AttachmentInfoService;
import com.css.fxfzcpxx.common.utils.UpdateUtil;
import com.css.fxfzcpxx.constants.FxfzConstants;
import com.css.fxfzcpxx.constants.YNEnum;
import com.css.fxfzcpxx.modules.earthquakeDisaster.entity.EarthquakeDisaster;
import com.css.fxfzcpxx.modules.earthquakeDisaster.param.EarthquakeDisasterParam;
import com.css.fxfzcpxx.modules.earthquakeDisaster.repository.EarthquakeDisasterRepository;
import com.css.fxfzcpxx.modules.earthquakeDisaster.service.EarthquakeDisasterService;
import com.css.fxfzcpxx.modules.earthquakeDisaster.vo.BasicDataSystemInfoVo;
import com.css.fxfzcpxx.modules.earthquakeDisaster.vo.EarthquakeDisasterVO;
import com.css.fxfzcpxx.util.EasyPoiExcelUtil;
import com.css.fxfzcpxx.util.PlatformDateUtils;
import com.css.fxfzcpxx.util.UUIDGenerator;
import com.css.fxfzcpxx.web.PlatformSessionContext;
import com.css.fxfzcpxx.zcpt.sys.service.SysAreaService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
import org.apache.poi.ss.usermodel.*;
import org.slw.common.helper.PropsHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.sql.Time;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: zhangSongRui
 * @CreateTime: 2023/02/28
 * @Description: 地震灾害信息
 */
@Service
public class EarthquakeDisasterServiceImpl implements EarthquakeDisasterService {
    @Resource
    private EarthquakeDisasterRepository earthquakeDisasterRepository;
    @Resource
    private AttachmentInfoService attachmentInfoService; // 附件
    @Resource
    private SysAreaService sysAreaService;
    @Autowired
    private RestTemplate restTemplate;

    @Value("${image.localDir}")
    private String localDir;

    //分页
    @Override
    public Map<String, Object> getPage(int curPage, int pageSize, EarthquakeDisasterParam param) {
        return earthquakeDisasterRepository.getPage(curPage, pageSize, param);
    }

    //查询单条数据
    @Override
    public EarthquakeDisasterVO findById(String id) {
        EarthquakeDisasterVO earthquakeDisasterVO = new EarthquakeDisasterVO();
        EarthquakeDisaster byId = earthquakeDisasterRepository.findById(id);
        UpdateUtil.copyNullProperties(byId, earthquakeDisasterVO);
        //典型震害照片
        if (!StringUtils.isEmpty(byId.getJedsZhzp())){
            String[] split = byId.getJedsZhzp().split(",");
            List<AttachmentInfoEntity> jedsZhzpList = new ArrayList<>();
            for (String s : split) {
                //根据id和文件名获取真实的放在磁盘上的文件
                AttachmentInfoEntity attachmentInfoEntity = attachmentInfoService.getAttach(s);
                jedsZhzpList.add(attachmentInfoEntity);
            }
            earthquakeDisasterVO.setJedsZhzpList(jedsZhzpList);
        }
        //等震线（图片）
        if (!StringUtils.isEmpty(byId.getIsolinePic())){
            String[] split = byId.getIsolinePic().split(",");
            List<AttachmentInfoEntity> isolinePicList = new ArrayList<>();
            for (String s : split) {
                //根据id和文件名获取真实的放在磁盘上的文件
                AttachmentInfoEntity attachmentInfoEntity = attachmentInfoService.getAttach(s);
                isolinePicList.add(attachmentInfoEntity);
            }
            earthquakeDisasterVO.setIsolinePicList(isolinePicList);
        }
        //烈度图
        if (!StringUtils.isEmpty(byId.getIntensityMap())){
            String[] split = byId.getIntensityMap().split(",");
            List<AttachmentInfoEntity> intensityMapList = new ArrayList<>();
            for (String s : split) {
                //根据id和文件名获取真实的放在磁盘上的文件
                AttachmentInfoEntity attachmentInfoEntity = attachmentInfoService.getAttach(s);
                intensityMapList.add(attachmentInfoEntity);
            }
            earthquakeDisasterVO.setIntensityMapList(intensityMapList);
        }
        //附件
        if (!StringUtils.isEmpty(byId.getAttachment())){
            String[] split = byId.getAttachment().split(",");
            List<AttachmentInfoEntity> attachmentList = new ArrayList<>();
            for (String s : split) {
                //根据id和文件名获取真实的放在磁盘上的文件
                AttachmentInfoEntity attachmentInfoEntity = attachmentInfoService.getAttach(s);
                attachmentList.add(attachmentInfoEntity);
            }
            earthquakeDisasterVO.setAttachmentList(attachmentList);
        }
        return earthquakeDisasterVO;
    }

    //删除单条数据
    @Override
    public void deleteById(String id) {
        earthquakeDisasterRepository.deleteById(id);
    }

    //修改发布状态
    @Override
    public void updateReleaseStatusById(List<String> id, String toString) {
        earthquakeDisasterRepository.updateReleaseStatusById(id, toString,new Date());
    }

    //根据id修改数据
    @Override
    public void updateById(EarthquakeDisaster param) {
        param.setUpdateUser(PlatformSessionContext.getUserID());
        param.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
        earthquakeDisasterRepository.updateById(param);
    }

    //导出
    @Override
    public void exportData(HttpServletResponse response, String id) {
        List<EarthquakeDisaster> list = earthquakeDisasterRepository.queryByParam(Arrays.asList(id.split(",")));
        EasyPoiExcelUtil.exportExcel(list, "地震灾害信息目录", "sheet1", EarthquakeDisaster.class, "地震灾害信息目录", response);
    }

    //模板导入
    @Override
    public String reportImport(InputStream inputStream) {
        try {
            Workbook workbook = WorkbookFactory.create(inputStream);
            Map<String, Object> map = getList(workbook);
            //获取校验结果
            if (!String.valueOf(map.get("message")).equals("正常")){
                return String.valueOf(map.get("message"));
            }
            earthquakeDisasterRepository.batchSave((List<EarthquakeDisaster>)map.get("list"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "导入成功";
    }

    @Override
    public void dockingBasicDataSystem(BasicDataSystemInfoVo basicDataSystemInfoVo) throws Exception {
        EarthquakeDisaster earthquakeDisaster=new EarthquakeDisaster();
        earthquakeDisaster.setCreateTime(new Date());
        earthquakeDisaster.setReleaseStatus("0");
        earthquakeDisaster.setDelFlag("0");
        earthquakeDisaster.setDataOrigin(FxfzConstants.FXFZ_JCSH);
        earthquakeDisaster.setReleaseDate(new Date());
        UpdateUtil.copyNullProperties(basicDataSystemInfoVo, earthquakeDisaster);
        earthquakeDisasterRepository.save(earthquakeDisaster);
    }

    @Override
    public void basicDataUpdate(BasicDataSystemInfoVo basicDataSystemInfoVo) throws Exception{
        StringBuilder attachIds=new StringBuilder("");
        String column="";
        List<MultipartFile> jedsZhzpFile = basicDataSystemInfoVo.getJedsZhzpFile();
        if (jedsZhzpFile != null && !(jedsZhzpFile.isEmpty())) {
            column="jeds_zhzp";
            for(MultipartFile file:jedsZhzpFile){
                attachIds.append(getfileUploadId(file)).append(",");
            }
        }

        List<MultipartFile> isolinePicFile = basicDataSystemInfoVo.getIsolinePicFile();
        if (isolinePicFile != null && !(isolinePicFile.isEmpty())) {
            column="isoline_pic";
            for(MultipartFile file:isolinePicFile){
                attachIds.append(getfileUploadId(file)).append(",");
            }
        }

        List<MultipartFile> intensityMapFile = basicDataSystemInfoVo.getIntensityMapFile();
        if (intensityMapFile != null && !(intensityMapFile.isEmpty())) {
            column="intensity_map";
            for(MultipartFile file:intensityMapFile){
                attachIds.append(getfileUploadId(file)).append(",");
            }
        }

        earthquakeDisasterRepository.updateAttachId(
                attachIds.substring(0, attachIds.length() - 1).toString(),
                column,basicDataSystemInfoVo.getJedsId());
    }


    public String getfileUploadId(MultipartFile file) throws IOException {
        //获取文件名称
        String fileName = file.getOriginalFilename();
        //获取文件上传的本地路径
        String dateDir = new SimpleDateFormat("/yyyy/MM/dd").format(new Date());
        String savePath = localDir + dateDir;
        //构建文件
        assert fileName != null;
        //上传文件
        String realFileName = uploadFile(fileName, savePath, file);
        //构建实体类
        AttachmentInfoEntity attachmentInfoEntity = buildAttachment(fileName, dateDir, realFileName);
        //保存附件到数据库
        attachmentInfoService.singleSave(attachmentInfoEntity);
        return attachmentInfoEntity.getAttachId();
    }
    private String uploadFile(String fileName, String savePath,MultipartFile multipartFile) throws IOException {
        // 获取文件的后缀名
        assert fileName != null;
        String preFileName = fileName.substring(0,fileName.lastIndexOf("."));
        // .jpg  .pdf  .txt  .docs
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        // 拼文件名  真实的文件名称
        String realFileName = preFileName + "_"  + System.currentTimeMillis() + fileType;
        //判断文件夹是否存在如果不存在则创建
        if(!new File(savePath).exists()){
            new File(savePath).mkdirs();
        }
        File file = new File(savePath, realFileName);
        multipartFile.transferTo(file);
        return realFileName;
    }

    private AttachmentInfoEntity buildAttachment(String fileName, String dateDir, String realFileName) {
        AttachmentInfoEntity attachmentInfoEntity = new AttachmentInfoEntity();
        attachmentInfoEntity.setAttachId(com.css.fxfzcpxx.util.StringUtils.buildPrimaryId());
        attachmentInfoEntity.setAttachName(fileName);
        attachmentInfoEntity.setAttachPath( dateDir + "/" + realFileName);
        attachmentInfoEntity.setFileDirId(localDir);
        attachmentInfoEntity.setIsValid("1");
        attachmentInfoEntity.setIsCompleted("1");
        return attachmentInfoEntity;
    }



    //获取list
    private Map<String, Object> getList(Workbook workbook) throws Exception {
        String userID = PlatformSessionContext.getUserID();
        Map<String, Object> map = new HashMap<>();
        //构筑物部分
        List<EarthquakeDisaster> list = new ArrayList<>();
        if (workbook != null) {
            //循环除了第一行的所有行
            /** 得到第一个sheet */
            Sheet sheet = workbook.getSheetAt(0);
            /** 得到Excel的行数 */
            int totalRows = sheet.getPhysicalNumberOfRows();
            HSSFDataFormatter hSSFDataFormatter = new HSSFDataFormatter();
            /** 循环Excel的行 从第七行开始*/
            for (int r = 3; r < totalRows; r++) {
                Row row = sheet.getRow(r);
                if (row == null) {
                    continue;
                }
                EarthquakeDisaster obj= new EarthquakeDisaster();
                //流水号
                String num = hSSFDataFormatter.formatCellValue(row.getCell(0));
                //主键id
                obj.setJedsId(UUID.randomUUID().toString().replaceAll("-", ""));
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(1)))){
                    map.put("message",num+"地震事件名称（简称）不能为空");
                }

                /*String province = hSSFDataFormatter.formatCellValue(row.getCell(2));
                String city = hSSFDataFormatter.formatCellValue(row.getCell(3));
                String county = hSSFDataFormatter.formatCellValue(row.getCell(4));
                if (StringUtils.isEmpty(province)|StringUtils.isEmpty(city)|StringUtils.isEmpty(county)){
                    map.put("message",num+"省市县字段不能为空");
                    break;
                }else {
                    // 根据省市县名称获得省市县id _ 分割
                    String divisionIds = sysAreaService.getIdByCondition(
                            URLEncoder.encode(hSSFDataFormatter.formatCellValue(row.getCell(2)), "UTF-8"),
                            URLEncoder.encode(hSSFDataFormatter.formatCellValue(row.getCell(3)), "UTF-8"),
                            URLEncoder.encode(hSSFDataFormatter.formatCellValue(row.getCell(4)), "UTF-8"));
                    //暂停一下,避免被认定为攻击
                    try {
                        TimeUnit.MILLISECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (StringUtils.isEmpty(divisionIds)){
                        map.put("message","序号: "+num+"的省市县不正确");
                        break;
                    }
                }*/

                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(2)))){
                    map.put("message",num+"参考位置");
                    break;
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(3)))){
                    map.put("message",num+"日期不能为空");
                    break;
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(4)))){
                    map.put("message",num+"时间不能为空");
                    break;
                }
                /*if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(5)))){
                    map.put("message",num+"微观震中地名不能为空");
                    break;
                }*/
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(6)))){
                    map.put("message",num+"宏观震中区域不能为空");
                    break;
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(7)))){
                    map.put("message",num+"经度不能为空");
                    break;
                }else{
                    String lon = hSSFDataFormatter.formatCellValue(row.getCell(7));
                    if(!(Double.parseDouble(lon) >= -180 && Double.parseDouble(lon) <= 180)){
                        map.put("message",num+"经度格式不正确");
                        break;
                    }
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(8)))){
                    map.put("message",num+"纬度不能为空");
                    break;
                }else{
                    String lat = hSSFDataFormatter.formatCellValue(row.getCell(8));
                    if(!(Double.parseDouble(lat) >= -90 && Double.parseDouble(lat) <= 90)){
                        map.put("message",num+"纬度格式不正确");
                        break;
                    }
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(9)))){
                    map.put("message",num+"震级不能为空");
                    break;
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(10)))){
                    map.put("message",num+"震源深度不能为空");
                    break;
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(11)))){
                    map.put("message",num+"最高烈度不能为空");
                    break;
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(12)))){
                    map.put("message",num+"死亡人数不能为空");
                    break;
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(14)))){
                    map.put("message",num+"受伤人数不能为空");
                    break;
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(15)))){
                    map.put("message",num+"震害现象描述不能为空");
                    break;
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(17)))){
                    map.put("message",num+"省不能为空");
                    break;
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(18)))){
                    map.put("message",num+"市不能为空");
                    break;
                }
                if (StringUtils.isEmpty(hSSFDataFormatter.formatCellValue(row.getCell(19)))){
                    map.put("message",num+"区县不能为空");
                    break;
                }
                //评地震事件名称(简称)
                obj.setEventAbbreviation(hSSFDataFormatter.formatCellValue(row.getCell(1)));

                List<Map<String,Object>> divisionList=getDivisionByLatAndLon(hSSFDataFormatter.formatCellValue(row.getCell(7)),hSSFDataFormatter.formatCellValue(row.getCell(8)));
                if(divisionList==null || divisionList.isEmpty()){
                    map.put("message",num+"请输入正确的经纬度");
                    break;
                }

                 obj.setProvince((String) divisionList.get(0).get("province"));
                obj.setCity((String) divisionList.get(0).get("city"));
                obj.setCounty((String) divisionList.get(0).get("county"));
                //参考位置
                obj.setReferencePosition(hSSFDataFormatter.formatCellValue(row.getCell(2)));
                //日期
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                obj.setJedsDate(dateFormat.parse(hSSFDataFormatter.formatCellValue(row.getCell(3))));
                //时间
                DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
                String s = hSSFDataFormatter.formatCellValue(row.getCell(4));
                Date parsedDate = timeFormat.parse(hSSFDataFormatter.formatCellValue(row.getCell(4)));
                obj.setJedsTime(new Time(parsedDate.getTime()));
                //微观震中地名
                obj.setLocation(hSSFDataFormatter.formatCellValue(row.getCell(5)));
                //宏观震中区域
                obj.setLocation1(hSSFDataFormatter.formatCellValue(row.getCell(6)));
                //经度
                obj.setJedsLongitude(Double.valueOf(hSSFDataFormatter.formatCellValue(row.getCell(7))));
                //维度
                obj.setJedsLatitude(Double.valueOf(hSSFDataFormatter.formatCellValue(row.getCell(8))));
                //震级
                obj.setMagnitude(hSSFDataFormatter.formatCellValue(row.getCell(9)));
                //震源深度
                obj.setDepth(Float.valueOf(hSSFDataFormatter.formatCellValue(row.getCell(10))));
                //最高烈度
                obj.setMaximumIntensity(hSSFDataFormatter.formatCellValue(row.getCell(11)));
                //死亡人数
                obj.setDeadNumber(Integer.valueOf(hSSFDataFormatter.formatCellValue(row.getCell(12))));
                //死亡原因
                obj.setCauseOfDeath(hSSFDataFormatter.formatCellValue(row.getCell(13)));
                //受伤人数
                obj.setInjuries(Integer.valueOf(hSSFDataFormatter.formatCellValue(row.getCell(14))));
                //震害现象描述
                obj.setDesEarthquakeDamage(hSSFDataFormatter.formatCellValue(row.getCell(15)));
                //备注
                obj.setNote(hSSFDataFormatter.formatCellValue(row.getCell(16)));
                //省
                obj.setProvince(hSSFDataFormatter.formatCellValue(row.getCell(17)));
                //市
                obj.setCity(hSSFDataFormatter.formatCellValue(row.getCell(18)));
                //区县
                obj.setCounty(hSSFDataFormatter.formatCellValue(row.getCell(19)));
                //0正常1删除
                obj.setDelFlag(YNEnum.N.toString());
                //0已发布，1未发布
                obj.setReleaseStatus(YNEnum.Y.toString());
                //创建人
                obj.setCreateUser(userID);
                //创建时间
                obj.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                obj.setDataOrigin(FxfzConstants.FXFZ_JCSH);
                list.add(obj);
            }
        }
        //写入正常
        if (map.size()==0){
            map.put("message","正常");
        }
        map.put("list",list);
        return map;
    }

    private List<Map<String, Object>> getDivisionByLatAndLon(String lon, String lat) {
        Properties configGroup = PropsHelper.loadProps("slw-config.properties");
        String url = configGroup.getProperty("sjxtRestUrl") + "/districtQuery/queryProvinceCityCountyNameCodeListByLonLat";
        JSONObject valueMap = new JSONObject();
        valueMap.put("lon", lon);
        valueMap.put("lat", lat);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", "fxfzcpxx");
        headers.set("subsystemCode", "dzxczhsspgzxt");
        HttpEntity<JSONObject> r = new HttpEntity<>(valueMap, headers);
        JSONArray data = restTemplate.exchange(url, HttpMethod.POST, r, JSONObject.class).getBody().getJSONArray("data");
        List<Map<String, Object>> list = new ArrayList<>();
        if(data.isEmpty()){
            return  list;
        }
        for (int i = 0; i < data.size(); i++) {
            JSONObject jsonObject = data.getJSONObject(i); // 获取每个元素的 JSONObject 对象
            Map<String, Object> map = jsonObject.toJavaObject(Map.class); // 将 JSONObject 转换为 Map
            list.add(map); // 将 Map 添加到 List 中
        }
        return list;
    }
}
